package com.nus.servlets;

import com.nus.beans.User;
import com.nus.beans.UserStatus;
import com.nus.database.DBManager;
import com.nus.database.LoginDBManager;
import com.nus.database.UserDBManager;
import com.nus.services.EncodingService;
import org.apache.log4j.Logger;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.util.Date;

/**
 * Created by IntelliJ IDEA.
 * User: dell
 * Date: 9/15/12
 * Time: 10:10 PM
 * To change this template use File | Settings | File Templates.
 */
public class LoginServlet extends AbstractServlet {
    private Logger logger = Logger.getLogger(this.getClass());

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        String loginName = request.getParameter("loginName");
        String password = request.getParameter("password");
        String nextPage;
        String errorMessage;
        EncodingService encodingService = new EncodingService();
        User user;
        boolean isUserBlocked = false;

        nextPage = "index.jsp";
        errorMessage = "Invlid User name or password. Please login again.";

        logger.info("Login request with username : " + loginName);

        if ((loginName != null && loginName.isEmpty())
                || password != null && password.isEmpty()) {
            errorMessage = "Both user name and password should not be empty";
            nextPage = "index.jsp";
        } else {
            String encodedPassword = encodingService.encode(password);
            Connection connection = getLoginDatabaseConnection();
            LoginDBManager loginDBManager = new LoginDBManager(connection);
            UserDBManager userDBManager = new UserDBManager(connection);
            loginName = loginName.toUpperCase();

            boolean loginStatus = loginDBManager.login(loginName, encodedPassword);
            logger.info("Login Status : " + loginStatus);
            user = loginDBManager.getUser(loginName);
            Date currentDate = new Date();
            if (user != null) {
                int userBlockedTime = Integer.parseInt(getServletContext().getInitParameter("USER_BLOCKED_TIME"));
                int maxFailedLoginAttemptsToBlock = Integer.parseInt(getServletContext().getInitParameter("NUMBER_ATTEMPTS_BLOCK"));

                if (user.getLastLoginFailedTime() != null && user.getFailedLoginAttempts() != 0 && user.getFailedLoginAttempts() % maxFailedLoginAttemptsToBlock == 0 &&
                        user.getLastLoginFailedTime().getTime() + userBlockedTime * 1000 > currentDate.getTime()) {
                    isUserBlocked = true;
                }

                if (!isUserBlocked) {
                    if (loginStatus) {
                        userDBManager.clearFailedLoginAttempts(user);

                        HttpSession session = request.getSession();
                        String dbURL = getConnectionURL();

                        DataSource userDataSource = DBManager.getUserDataSource(dbURL, user);
                        boolean isDataSourceActive = DBManager.testDataSource(userDataSource);
                        if (isDataSourceActive) {
                            session.setAttribute("user_data_source", userDataSource);
                            session.setAttribute("user", user);
                            nextPage = "/WEB-INF/developer_home.jsp";
                        } else {
                            errorMessage = "System error.";
                        }
                    } else {
                        user = loginDBManager.getUser(loginName);
                        if (user != null) {
                            int maxFailedLoginAttemptsToDelete = Integer.parseInt(getServletContext().getInitParameter("NUMBER_ATTEMPTS_DELETE"));
                            int failedLoginATtempts = userDBManager.getFailedLoginAttempts(user);
                            failedLoginATtempts++;
                            if (failedLoginATtempts >= maxFailedLoginAttemptsToDelete) {
                                userDBManager.deleteUser(user);
                            } else {
                                userDBManager.increametFailedAttempt(user);
                            }
                        }
                    }
                }
            }
        }

        request.setAttribute("ERROR_MESSAGE", errorMessage);
        RequestDispatcher dispatcher = request.getRequestDispatcher(nextPage);
        dispatcher.forward(request, response);
    }
}
